package com.bong.panpan.bongcharttools;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.graphics.Color;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;

import com.bong.panpan.bongcharttools.ble.BleDeviceState;
import com.bong.panpan.bongcharttools.ble.BleLink;
import com.bong.panpan.bongcharttools.custom.Constant;
import com.bong.panpan.bongcharttools.custom.MyMarkerView;
import com.bong.panpan.bongcharttools.custom.MyProtocol;
import com.bong.panpan.bongcharttools.custom.MyUtil;
import com.bong.panpan.bongcharttools.custom.PPGECGRecord;
import com.bong.panpan.bongcharttools.custom.SpUtil;
import com.bong.panpan.bongcharttools.custom.UserInfoRecord;
import com.bong.panpan.bongcharttools.util.Common;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.AxisBase;
import com.github.mikephil.charting.components.Description;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.formatter.DefaultValueFormatter;
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
import com.github.mikephil.charting.listener.ChartTouchListener;
import com.github.mikephil.charting.listener.OnChartGestureListener;
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;

/**
 * Created by panpan on 2017/9/26.
 */

public class ChartShowHelper2 implements OnChartGestureListener, OnChartValueSelectedListener, MyProtocol.OnProtocalDealListener {

    LineChart mChart;
    Button beginBtn;
    Button clearBtn;
    Button saveBtn;
    Button loadBtn;
    CheckBox[] checks;
    Spinner modeSpinner;
    View menuLayout;
    TextView[] textValue;
    Activity activity;

    private BleLink bleLink;
    private ChartEntryAdd chartEntryAdd;
    private int[] valueData;
    public UserInfoRecord userInfoRecord;
    private int ECGMinNum = -1000;
    private int ECGMaxNum = 1000;
    private long beginTime = 0;
    private int measureTime = 0;
    private final int PPGYMaxNum = 3300000;
    private final int PPGYMinNum = 2800000;
    //private final int colors[] = new int[]{Color.GREEN, Color.YELLOW, 0xfff9aa50, 0xff7a9bff, 0xffd29eff};

    public ChartShowHelper2(LineChart mChart,
                            final Button beginBtn,
                            Button saveBtn,
                            Button clearBtn,
                            Button loadBtn,
                            CheckBox[] checks,
                            Spinner modeSpinner,
                            View menuLayout,
                            TextView[] textValue,
                            final Activity activity) {
        this.mChart = mChart;
        this.beginBtn = beginBtn;
        this.saveBtn = saveBtn;
        this.clearBtn = clearBtn;
        this.loadBtn = loadBtn;
        this.checks = checks;
        this.modeSpinner = modeSpinner;
        this.menuLayout = menuLayout;
        this.textValue = textValue;
        this.activity = activity;
        chartInit();
        for (int i = 0; i < checks.length; i++) {
            checks[i].setOnCheckedChangeListener(checkedChangeListener);
        }
        modeSpinner.setOnItemSelectedListener(spinnerListener);
        bleLink = ((MainActivity2) activity).getDeviceSelectHelper().getBleLink();
        int position = SpUtil.getInstance().getInt("ChartShowHelper:modeSpinner", 0);
        this.modeSpinner.setSelection(position);
        boolean checked = SpUtil.getInstance().getBoolean("ChartShowHelper:valueCheck", false);
        checks[0].setChecked(checked);
        checked = SpUtil.getInstance().getBoolean("ChartShowHelper:circleCheck", false);
        checks[1].setChecked(checked);
        checked = SpUtil.getInstance().getBoolean("ChartShowHelper:high_light_check", false);
        checks[2].setChecked(checked);
        checked = SpUtil.getInstance().getBoolean("ChartShowHelper:lineCheck1", true);
        checks[3].setChecked(checked);
        checked = SpUtil.getInstance().getBoolean("ChartShowHelper:lineCheck2", true);
        checks[4].setChecked(checked);
        try {
            if (loadChartData(Constant.cacheChartPath))
                Common.showToast(activity, "读取缓存成功");
        } catch (Exception e) {
            e.printStackTrace();
        }
        bleLink.addBleListener(new BleLink.BleListener() {
            @Override
            public void OnDeviceStateChanged(BleLink bleLink, BleDeviceState state) {
                if (state == BleDeviceState.DEVICE_STATE_DISLINK) {
                    activity.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            if ("开始".equals(beginBtn.getText().toString())) {

                            } else {
                                beginClick(beginBtn);
                            }
                        }
                    });
                }
            }

            @Override
            public void OnDataReceived(BleLink bleLink, byte[] data) {

            }
        });
    }

    private void chartInit() {
        mChart.setOnChartGestureListener(this);
        mChart.setOnChartValueSelectedListener(this);
        mChart.setDrawGridBackground(false);

        // no description text
        //mChart.getDescription().setEnabled(false);
        Description desc = new Description();
        desc.setText("bong");
        mChart.setDescription(desc);

        // enable touch gestures
        mChart.setTouchEnabled(true);

        // enable scaling and dragging
        mChart.setDragEnabled(true);
        mChart.setScaleEnabled(true);
        mChart.setScaleXEnabled(true);
        mChart.setScaleYEnabled(true);

        // if disabled, scaling can be done on x- and y-axis separately
        mChart.setPinchZoom(false);
        // set an alternative background color
        // mChart.setBackgroundColor(Color.GRAY);

        // create a custom MarkerView (extend MarkerView) and specify the layout
        // to use for it
        MyMarkerView mv = new MyMarkerView(activity, R.layout.custom_marker_view);
        mv.setChartView(mChart); // For bounds control
        mChart.setMarker(mv); // Set the marker to the chart

        YAxis leftAxis = mChart.getAxisLeft();
        leftAxis.setTextColor(Color.RED);
        leftAxis.setAxisMaximum(PPGYMaxNum);
        leftAxis.setAxisMinimum(PPGYMinNum);
        leftAxis.enableGridDashedLine(10f, 10f, 0f);
        leftAxis.setDrawZeroLine(false);
        leftAxis.setDrawGridLines(true);
        leftAxis.setGranularityEnabled(true);
        leftAxis.setValueFormatter(new IAxisValueFormatter() {
            @Override
            public String getFormattedValue(float value, AxisBase axis) {
                if ((int) value % 10000 == 0)
                    return (int) value / 10000 + "w";
                return "" + (int) value;
            }
        });


        YAxis rightAxis = mChart.getAxisRight();
        rightAxis.setTextColor(Color.BLUE);
        rightAxis.setAxisMaximum(4000);
        rightAxis.setAxisMinimum(-2000);
        rightAxis.setDrawGridLines(false);
        rightAxis.setDrawZeroLine(false);
        rightAxis.setGranularityEnabled(false);
        rightAxis.setValueFormatter(new IAxisValueFormatter() {
            @Override
            public String getFormattedValue(float value, AxisBase axis) {
                if ((int) value % 1000 == 0)
                    return (int) value / 1000 + "k";
                return "" + (int) value;
            }
        });

        XAxis xAxis = mChart.getXAxis();
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.enableGridDashedLine(10f, 10f, 0f);
        xAxis.setAxisMinimum(0);
        xAxis.setAxisMaximum(500);
        xAxis.setAvoidFirstLastClipping(true);
        xAxis.setValueFormatter(new IAxisValueFormatter() {
            @Override
            public String getFormattedValue(float value, AxisBase axis) {
                if ((int) value % 1000 == 0)
                    return (int) value / 1000 + "k";
                return "" + (int) value;
            }
        });

        //mChart.setVisibleXRangeMaximum(20);

        mChart.setHighlightPerDragEnabled(true);
        mChart.setDoubleTapToZoomEnabled(false);
        //mChart.setAutoScaleMinMaxEnabled(true);

        // add data
        chartEntryAdd = new ChartEntryAdd();

        // get the legend (only possible after setting data)
        Legend l = mChart.getLegend();

        // modify the legend ...
        l.setForm(Legend.LegendForm.LINE);

        // // dont forget to refresh the drawing
        // mChart.invalidate();
    }

    /**
     * 加载特定的数据
     */
    public boolean loadChartData(String path) {
        onClearClicked();
        PPGECGRecord ppgecgRecord = PPGECGRecord.load(path);
        if (ppgecgRecord != null) {
            chartEntryAdd.chartCacheData = ppgecgRecord.chartData;
            valueData = ppgecgRecord.values;
            chartEntryAdd.uiRunnable.run();
            measureTime = ppgecgRecord.measureTime;
            textValue[3].setText(String.format("测量时间：%02d:%02d", measureTime / 1000 / 60, measureTime / 1000 % 60));
            return true;
        }
        return false;
    }

    public void beginClick(View v) {
        if ("开始".equals(beginBtn.getText().toString())) {
            if (bleLink.getDeviceState() == BleDeviceState.DEVICE_STATE_LINKED) {
                if (MyProtocol.sendData(bleLink, true, userInfoRecord)) {
                    onClearClicked();
                    startChartThread();
                    saveBtn.setEnabled(false);
                    clearBtn.setEnabled(false);
                    loadBtn.setEnabled(false);
                    beginBtn.setText("停止");
                    ((MainActivity2) activity).getDeviceSelectHelper().protocol.reset();
                } else {
                    Common.showToast(activity, "数据发送失败");
                }
            } else {
                Common.showToast(activity, "蓝牙连接未就绪");
            }
        } else {
            if (bleLink.getDeviceState() == BleDeviceState.DEVICE_STATE_LINKED) {
                if (MyProtocol.sendData(bleLink, false, userInfoRecord)) {
                } else {
                    Common.showToast(activity, "数据发送失败");
                }
            } else {
                Common.showToast(activity, "蓝牙连接未就绪");
            }
            saveBtn.setEnabled(true);
            clearBtn.setEnabled(true);
            loadBtn.setEnabled(true);
            beginBtn.setText("开始");
            measureTime = (int) (System.currentTimeMillis() - beginTime);
            textValue[3].setText(String.format("测量时间：%02d:%02d", measureTime / 1000 / 60, measureTime / 1000 % 60));
        }
    }

    private AlertDialog alertDialog;
    private EditText alertEdit;
    private TextWatcher alertEditListerner = new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {
            if (!"".equals(s.toString())) {
                alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true);
            }
        }
    };

    private void saveFile(String fileName) throws Exception {
        File file = new File(Constant.chartsStorePath + "/" + fileName + Constant.chartEndName);
        if (file.exists() && file.isFile())
            throw new Exception("文件\"" + fileName + "\"已存在，请使用其他的文件名");
        PPGECGRecord ppgecgRecord = new PPGECGRecord();
        ppgecgRecord.userInfoRecord = userInfoRecord;
        ppgecgRecord.chartData = chartEntryAdd.chartCacheData;
        ppgecgRecord.values = valueData;
        ppgecgRecord.measureTime = measureTime;
        if (!PPGECGRecord.save(ppgecgRecord, file.getPath()))
            throw new Exception("保存失败");
    }

    public void saveClick(View v) {
        if (mChart.getData() == null) {
            MyUtil.showToast(activity, "没有可以保存的数据");
            return;
        }
        if (alertDialog == null) {
            AlertDialog.Builder builder = new AlertDialog.Builder(activity);
            builder.setTitle("提示");
            alertEdit = new EditText(activity);
            alertEdit.setHint("请输入文件名");
            alertEdit.addTextChangedListener(alertEditListerner);
            builder.setView(alertEdit);
            builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    String fileName = alertEdit.getText().toString();
                    try {
                        saveFile(fileName);
                        Common.showToast(activity, "保存成功");
                        ((MainActivity2) activity).getChartListFragment().refreshList();
                    } catch (Exception e) {
                        e.printStackTrace();
                        Common.showToast(activity, "保存失败\n" + e.getMessage());
                    }
                    alertEdit.clearFocus();
                    MyUtil.closeKeybord(activity);
                }
            });
            builder.setNegativeButton("取消", null);
            alertDialog = builder.create();
        }
        alertEdit.setText("");
        alertDialog.show();
        alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
    }

    public void onClearClicked() {
        chartEntryAdd.isInit = false;
        valueData = null;
        chartEntryAdd.chartCacheData.clear();
        mChart.clear();
        mChart.invalidate();
        textValue[0].setText("高压：空");
        textValue[1].setText("低压：空");
        textValue[2].setText("心率：空");
        textValue[3].setText("测量时间：00:00");
        measureTime = 0;
        ECGMinNum = -1000;
        ECGMaxNum = 1000;
        YAxis rightAxis = mChart.getAxisRight();
        rightAxis.setAxisMaximum(4000);
        rightAxis.setAxisMinimum(-2000);
        YAxis leftAxis = mChart.getAxisLeft();
        leftAxis.setAxisMaximum(PPGYMaxNum);
        leftAxis.setAxisMinimum(PPGYMinNum);
        MyUtil.showToast(activity, "数据已清空");
    }

    private CompoundButton.OnCheckedChangeListener checkedChangeListener = new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            List<ILineDataSet> sets;
            switch (buttonView.getId()) {
                case R.id.value_check:
                    SpUtil.getInstance().setBoolean("ChartShowHelper:valueCheck", isChecked);
                    if (mChart.getData() == null)
                        break;
                    sets = mChart.getData()
                            .getDataSets();

                    for (ILineDataSet iSet : sets) {

                        LineDataSet set = (LineDataSet) iSet;
                        set.setDrawValues(isChecked);
                    }

                    mChart.invalidate();
                    break;
                case R.id.circle_check:
                    SpUtil.getInstance().setBoolean("ChartShowHelper:circleCheck", isChecked);
                    if (mChart.getData() == null)
                        break;
                    sets = mChart.getData()
                            .getDataSets();

                    for (ILineDataSet iSet : sets) {

                        LineDataSet set = (LineDataSet) iSet;
                        set.setDrawCircles(isChecked);
                    }
                    mChart.invalidate();
                    break;
                case R.id.high_light_check:
                    SpUtil.getInstance().setBoolean("ChartShowHelper:high_light_check", isChecked);
                    if (mChart.getData() == null)
                        break;
                    sets = mChart.getData()
                            .getDataSets();

                    for (ILineDataSet iSet : sets) {

                        LineDataSet set = (LineDataSet) iSet;
                        set.setHighlightEnabled(isChecked);
                    }
                    mChart.invalidate();
                    break;
                case R.id.line_check1:
                    SpUtil.getInstance().setBoolean("ChartShowHelper:lineCheck1", isChecked);
                    if (mChart.getData() == null)
                        break;
                    sets = mChart.getData()
                            .getDataSets();
                    if (sets.size() == 0)
                        break;
                    sets.get(0).setVisible(isChecked);
                    mChart.invalidate();
                    break;
                case R.id.line_check2:
                    SpUtil.getInstance().setBoolean("ChartShowHelper:lineCheck2", isChecked);
                    if (mChart.getData() == null)
                        break;
                    sets = mChart.getData()
                            .getDataSets();
                    if (sets.size() < 2)
                        break;
                    sets.get(1).setVisible(isChecked);
                    mChart.invalidate();
                    break;
                default:
                    break;
            }
        }
    };
    private AdapterView.OnItemSelectedListener spinnerListener = new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            SpUtil.getInstance().setInt("ChartShowHelper:modeSpinner", position);
            if (mChart.getData() == null)
                return;
            List<ILineDataSet> sets = mChart.getData().getDataSets();

            for (ILineDataSet iSet : sets) {

                LineDataSet set = (LineDataSet) iSet;
                set.setMode(LineDataSet.Mode.values()[position]);
            }
            mChart.invalidate();
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {

        }
    };

    private LineDataSet createSet(int index) {
        String label = "PPG";
        int color = Color.RED;
        if (index == 1) {
            label = "ECG";
            color = Color.BLUE;
        }
        LineDataSet set = new LineDataSet(null, label);
        if (index == 0)
            set.setAxisDependency(YAxis.AxisDependency.LEFT);
        else
            set.setAxisDependency(YAxis.AxisDependency.RIGHT);
        set.setColor(color);
        set.setCircleColor(color);
        set.setLineWidth(1f);
        set.setCircleRadius(3f);
        //set.setFillAlpha(65);
        //set.setFillColor(ColorTemplate.getHoloBlue());
        set.setHighLightColor(color);
        set.setValueTextColor(color);
        set.setValueTextSize(9f);
        set.setDrawValues(false);
        set.setFormLineWidth(1f);
        set.setValueFormatter(new DefaultValueFormatter(0));
        set.enableDashedHighlightLine(10f, 5f, 0f);
        return set;
    }

    /**
     * Callbacks when a touch-gesture has started on the chart (ACTION_DOWN)
     *
     * @param me
     * @param lastPerformedGesture
     */
    @Override
    public void onChartGestureStart(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {

    }

    /**
     * Callbacks when a touch-gesture has ended on the chart (ACTION_UP, ACTION_CANCEL)
     *
     * @param me
     * @param lastPerformedGesture
     */
    @Override
    public void onChartGestureEnd(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {

    }

    /**
     * Callbacks when the chart is longpressed.
     *
     * @param me
     */
    @Override
    public void onChartLongPressed(MotionEvent me) {

    }

    /**
     * Callbacks when the chart is double-tapped.
     *
     * @param me
     */
    @Override
    public void onChartDoubleTapped(MotionEvent me) {
        if ("开始".equals(beginBtn.getText().toString()))
            onClearClicked();
    }

    /**
     * Callbacks when the chart is single-tapped.
     *
     * @param me
     */
    @Override
    public void onChartSingleTapped(MotionEvent me) {

    }

    /**
     * Callbacks then a fling gesture is made on the chart.
     *
     * @param me1
     * @param me2
     * @param velocityX
     * @param velocityY
     */
    @Override
    public void onChartFling(MotionEvent me1, MotionEvent me2, float velocityX, float velocityY) {

    }

    /**
     * Callbacks when the chart is scaled / zoomed via pinch zoom gesture.
     *
     * @param me
     * @param scaleX scalefactor on the x-axis
     * @param scaleY scalefactor on the y-axis
     */
    @Override
    public void onChartScale(MotionEvent me, float scaleX, float scaleY) {

    }

    /**
     * Callbacks when the chart is moved / translated via drag gesture.
     *
     * @param me
     * @param dX translation distance on the x-axis
     * @param dY translation distance on the y-axis
     */
    @Override
    public void onChartTranslate(MotionEvent me, float dX, float dY) {

    }

    /**
     * Called when a value has been selected inside the chart.
     *
     * @param e The selected Entry
     * @param h The corresponding highlight object that contains information
     */
    @Override
    public void onValueSelected(Entry e, Highlight h) {

    }

    /**
     * Called when nothing has been selected or an "un-select" has been made.
     */
    @Override
    public void onNothingSelected() {

    }

    @Override
    public void OnProtocalReceived(byte... data) {

    }

    @Override
    public void OnProtocalReceivedBytes(final int bytes, final int bytes2) {
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (bytes != bytes2) {
                    MyUtil.showAlertDialog(activity, "数据接收出错", "发送数据：" + MyUtil.getFileLengthString(bytes) + "\n接收数据：" + MyUtil.getFileLengthString(bytes2) + "\n数据长度不一致", null);
                } else {
                    MyUtil.showToast(activity, "接收数据：" + MyUtil.getFileLengthString(bytes));
                }
            }
        });

    }

    @Override
    public void OnProtocalDealOk(int cmd, int[] data, int[] valueData) {
        if (cmd == 0x2F) {
            chartEntryAdd.put(data);
            this.valueData = valueData;
            //Log.i("num",""+data.length);
        }
    }

    public void onDestory() {
        if (chartThread != null && chartThread.isAlive()) {
            chartThread.interrupt();
            chartThread = null;
        }
        try {
            //保存缓存
            if (mChart.getData() != null) {
                PPGECGRecord ppgecgRecord = new PPGECGRecord();
                ppgecgRecord.chartData = chartEntryAdd.chartCacheData;
                ppgecgRecord.values = valueData;
                ppgecgRecord.measureTime = measureTime;
                PPGECGRecord.save(ppgecgRecord, Constant.cacheChartPath);
            }
        } catch (Exception e) {

        }
    }

    private Thread chartThread;

    private void startChartThread() {
        beginTime = System.currentTimeMillis();
        if (chartThread == null || !chartThread.isAlive()) {
            chartThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        try {
                            chartEntryAdd.refresh();
                        } catch (InterruptedException e) {
                            Log.i("UI", "ChartThread Stopped!");
                            break;
                        }
                    }
                }
            });
            chartThread.setPriority(Thread.MIN_PRIORITY);
            chartThread.setName("UI 更新线程");
        }
        if (!chartThread.isAlive())
            chartThread.start();
    }

    class ChartEntryAdd {
        final Semaphore semaphore = new Semaphore(0);
        ILineDataSet set1, set2;
        LineData data;
        boolean isInit = false;
        ArrayList<int[]> chartCacheData = new ArrayList<>();
        private int index = 0;

        public ChartEntryAdd() {
        }

        public void put(int... chartData) {
            chartCacheData.add(chartData);
            if (semaphore.availablePermits() == 0)
                semaphore.release();
        }

        private Runnable uiRunnable = new Runnable() {
            @Override
            public void run() {
                if (!isInit) {
                    LineData data = new LineData();
                    // add empty data
                    mChart.setData(data);
                    ChartEntryAdd.this.data = data;
                    if (data != null) {
                        set1 = data.getDataSetByIndex(0);
                        if (set1 == null) {
                            set1 = createSet(0);
                            data.addDataSet(set1);
                        }
                        set2 = data.getDataSetByIndex(1);
                        if (set2 == null) {
                            set2 = createSet(1);
                            data.addDataSet(set2);
                        }
                    }
                    ((LineDataSet) set1).setMode(LineDataSet.Mode.values()[modeSpinner.getSelectedItemPosition()]);
                    ((LineDataSet) set1).setDrawValues(checks[0].isChecked());
                    ((LineDataSet) set1).setDrawCircles(checks[1].isChecked());
                    ((LineDataSet) set1).setHighlightEnabled(checks[2].isChecked());
                    ((LineDataSet) set1).setVisible(checks[3].isChecked());

                    ((LineDataSet) set2).setMode(LineDataSet.Mode.values()[modeSpinner.getSelectedItemPosition()]);
                    ((LineDataSet) set2).setDrawCircles(checks[0].isChecked());
                    ((LineDataSet) set2).setDrawCircles(checks[1].isChecked());
                    ((LineDataSet) set2).setHighlightEnabled(checks[2].isChecked());
                    ((LineDataSet) set2).setVisible(checks[3].isChecked());
                    index = 0;
                    isInit = true;
                }
                int size = chartCacheData.size();
                int num = chartCacheData.get(0).length / 2;//计算坐标数目（一组坐标2个）
                int temp;
                if (index < size) {
                    if (set1.getEntryCount() > 499) {
                        set1.clear();
                        set2.clear();
                        ECGMinNum = -1000;
                        ECGMaxNum = 1000;
                        YAxis rightAxis = mChart.getAxisRight();
                        rightAxis.setAxisMaximum(4000);
                        rightAxis.setAxisMinimum(-2000);
                        YAxis leftAxis = mChart.getAxisLeft();
                        leftAxis.setAxisMaximum(PPGYMaxNum);
                        leftAxis.setAxisMinimum(PPGYMinNum);
                    }
                    float leftYChangedNum;
                    float tempLeftNum;
                    int boundNum = 50000;
                    for (int i = index; i < size; i++) {
                        for (int j = 0; j < num; j++) {
                            data.addEntry(new Entry(set1.getEntryCount(), temp = MyUtil.uint2Int(chartCacheData.get(i)[j * 2])), 0);
                            tempLeftNum = mChart.getAxisLeft().getAxisMaximum();
                            if (temp > tempLeftNum) {
                                if (temp - tempLeftNum < Float.MAX_VALUE - (boundNum - 1)) {
                                    leftYChangedNum = (int) (temp - tempLeftNum + (boundNum - 1)) / boundNum;
                                    if (tempLeftNum < Float.MAX_VALUE - leftYChangedNum * boundNum) {
                                        mChart.getAxisLeft().setAxisMaximum(tempLeftNum + leftYChangedNum * boundNum);
                                        mChart.getAxisLeft().setAxisMinimum(mChart.getAxisLeft().getAxisMinimum() + leftYChangedNum * boundNum);
                                    } else {
                                        mChart.getAxisLeft().setAxisMaximum(Float.MAX_VALUE);
                                        mChart.getAxisLeft().setAxisMinimum(Float.MAX_VALUE - (PPGYMaxNum - PPGYMinNum));
                                    }
                                } else {
                                    mChart.getAxisLeft().setAxisMaximum(Float.MAX_VALUE);
                                    mChart.getAxisLeft().setAxisMinimum(Float.MAX_VALUE - (PPGYMaxNum - PPGYMinNum));
                                }
                            }
                            tempLeftNum = mChart.getAxisLeft().getAxisMinimum();
                            if (temp < tempLeftNum + (PPGYMaxNum - PPGYMinNum) / 2) {
                                leftYChangedNum = (tempLeftNum + (PPGYMaxNum - PPGYMinNum) / 2 - temp + (boundNum - 1)) / boundNum;
                                mChart.getAxisLeft().setAxisMaximum(mChart.getAxisLeft().getAxisMaximum() - leftYChangedNum * boundNum);
                                mChart.getAxisLeft().setAxisMinimum(tempLeftNum - leftYChangedNum * boundNum);
                            }
                            data.addEntry(new Entry(set2.getEntryCount(), temp = MyUtil.uint2Int(chartCacheData.get(i)[j * 2 + 1])), 1);
                            if (temp < ECGMinNum)
                                ECGMinNum = temp;
                            if (temp > ECGMaxNum)
                                ECGMaxNum = temp;
                        }
                        index++;
                        if (set1.getEntryCount() > 499) {
                            break;
                        }
                    }
                }
                if (ECGMinNum < -1000) {
                    YAxis rightAxis = mChart.getAxisRight();
                    rightAxis.setAxisMaximum(((-ECGMinNum) / 1000 + 1) * 4000);
                    rightAxis.setAxisMinimum(((-ECGMinNum) / 1000 + 1) * -2000);
                }
                if (ECGMaxNum > 1000) {
                    YAxis rightAxis = mChart.getAxisRight();
                    rightAxis.setAxisMaximum((ECGMaxNum / 1000 + 1) * 4000);
                    rightAxis.setAxisMinimum((ECGMaxNum / 1000 + 1) * -2000);
                }
                data.notifyDataChanged();
                mChart.notifyDataSetChanged();
                //mChart.setVisibleXRangeMaximum(1000);
                mChart.invalidate();
                if (valueData != null && valueData.length > 0)
                    textValue[0].setText("高压：" + valueData[0]);
                else
                    textValue[0].setText("高压：空");

                if (valueData != null && valueData.length > 1)
                    textValue[1].setText("低压：" + valueData[1]);
                else
                    textValue[1].setText("低压：空");

                if (valueData != null && valueData.length > 2)
                    textValue[2].setText("心率：" + valueData[2]);
                else
                    textValue[2].setText("心率：空");
                measureTime = (int) (System.currentTimeMillis() - beginTime);
                textValue[3].setText(String.format("测量时间：%02d:%02d", measureTime / 1000 / 60, measureTime / 1000 % 60));
            }
        };

        public void refresh() throws InterruptedException {
            semaphore.acquire();
            activity.runOnUiThread(uiRunnable);
            Thread.sleep(20);//50fps
        }
    }
}
